<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- base href="http://www.codeslinger.co.uk/pages/projects/gameboy/joypad.html" --></head><body><div style="background:#fff;border:1px solid #999;margin:-1px -1px 0;padding:0;"><div style="background:#ddd;border:1px solid #999;color:#000;font:13px arial,sans-serif;font-weight:normal;margin:12px;padding:8px;text-align:left">Esta es la versión en caché de <a href="http://www.codeslinger.co.uk/pages/projects/gameboy/joypad.html" style="text-decoration: underline; color: rgb(0, 0, 204);">http://www.codeslinger.co.uk/pages/projects/gameboy/joypad.html</a>
 de Google. Se trata de una captura de pantalla de la página tal como 
esta se mostraba el 9 May 2011 04:37:29 GMT. Es posible que la <a href="http://www.codeslinger.co.uk/pages/projects/gameboy/joypad.html" style="text-decoration: underline; color: rgb(0, 0, 204);">página</a> haya sufrido modificaciones durante este tiempo. <a href="http://www.google.com/intl/es/help/features_list.html#cached" style="text-decoration: underline; color: rgb(0, 0, 204);">Más información</a><br><br><div style="float:right"><a href="http://webcache.googleusercontent.com/search?q=cache:6ZdI3UA8RBAJ:www.codeslinger.co.uk/pages/projects/gameboy/joypad.html+codeslinger+gameboy+joypad+emulation&amp;hl=es&amp;gl=ar&amp;strip=1" style="text-decoration: underline; color: rgb(0, 0, 204);">Versión de solo texto</a></div>
<div>Se han resaltado estos términos de búsqueda: <span style="background:#ffff66;color:black;font-weight:bold">codeslinger</span>&nbsp;<span style="background:#a0ffff;color:black;font-weight:bold">gameboy</span>&nbsp;<span style="background:#99ff99;color:black;font-weight:bold">joypad</span>&nbsp;<span style="background:#ff9999;color:black;font-weight:bold">emulation</span>&nbsp;&nbsp;</div></div></div><div style="position:relative">



<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="description" content="_Emulation Programming_">
<meta name="keywords" content="_Emulation,Chip8,Gameboy,NES,SNES,Genesis,Master,System,Mega,Drive_">
<meta name="author" content="CodeSlinger /">
<link rel="stylesheet" type="text/css" href="10%20Joypad%20Emulation_files/css.css" media="screen,projection" title="CodeSlinger (screen)">
<link rel="stylesheet" type="text/css" href="10%20Joypad%20Emulation_files/print.css" media="print">
<title>codeslinger.co.uk</title>



<div>
<br><br>
</div>

<div id="container">
<div id="logo">
<h1><a href="http://www.codeslinger.co.uk/index.html"><b style="color:black;background-color:#ffff66">codeslinger</b>.co.uk</a></h1>
</div>

<div id="navitabs">
<h2 class="hide">Site menu:</h2>
<a class="navitab" href="http://www.codeslinger.co.uk/index.php">Home</a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/basics.html">Basics</a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/projects/zuko.html">Zuko</a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/projects/megadrive.html">Mega Drive/Genesis</a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/projects/mastersystem.html">Master System</a><span class="hide"> | </span>
<a class="activenavitab" href="http://www.codeslinger.co.uk/pages/projects/gameboy.html"><b style="color:black;background-color:#a0ffff">Gameboy</b></a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/projects/chip8.html">Chip8</a><span class="hide"> | </span>
<a class="navitab" href="http://www.codeslinger.co.uk/pages/blog/index.html">Blog</a><span class="hide"> | </span>
</div>
	
<div id="desc">
<h2><b style="color:black;background-color:#ffff66">codeslinger</b>.co.uk</h2>
<p> <b style="color:black;background-color:#a0ffff">Gameboy</b> - <b style="color:black;background-color:#99ff99">Joypad</b>.</p>

</div>

<div id="main">

<h3><b><b style="color:black;background-color:#99ff99">Joypad</b>:</b></h3>
<p>
The <b style="color:black;background-color:#a0ffff">gameboy</b> has an inbuilt <b style="color:black;background-color:#99ff99">joypad</b> with 8 buttons. There are 4 directional buttons (up, down, left and right) and standard
buttons (start,select, A and B). The <b style="color:black;background-color:#99ff99">joypad</b> register can be found at address 0xFF00 and it is broken down like so:

</p><p class="block">
Taken from pandocs<br>
  Bit 7 - Not used<br>
  Bit 6 - Not used<br>
  Bit 5 - P15 Select Button Keys      (0=Select)<br>
  Bit 4 - P14 Select Direction Keys   (0=Select)<br>
  Bit 3 - P13 Input Down  or Start    (0=Pressed) (Read Only)<br>
  Bit 2 - P12 Input Up    or Select   (0=Pressed) (Read Only)<br>
  Bit 1 - P11 Input Left  or Button B (0=Pressed) (Read Only)<br>
  Bit 0 - P10 Input Right or Button A (0=Pressed) (Read Only)
</p>
Bits 0-3 are set by the emulator to show the state of the <b style="color:black;background-color:#99ff99">joypad</b>. As you can see the directional buttons
and the standard buttons share this range of bits so how would the game know if bit 3 was set whether it was
the directional down button or the stanadrd start button? The way this works is that the game sets bit 4 and 5
depending on whether it wants to check on the directional buttons or the standard buttons.<br><br>

The way I believe this works in the original <b style="color:black;background-color:#a0ffff">gameboy</b> hardware is the game writes to memory 0xFF00 with bit 4 or 5 set
(never both). It then reads from memory 0xFF00 and instead of reading back what it just wrote what is returned is the
state of the <b style="color:black;background-color:#99ff99">joypad</b> 
based on whether bit 4 or bit 5 was set. For example if the game wanted 
to check which directional buttons
was pressed it would set bit 4 to 1 and then it would do a read memory 
on 0xFF00.
If the up key is pressed then when reading 0xFF00 bit 2 would be set to 0
 to signal that the directional button up is pressed (0 means pressed, 1
 unpressed).
However if up was not pressed but the select button was then bit 2 would
 be left at 1 meaning nothing is pressed, even though
the select button is pressed which maps on to bit 2. The reason why bit 2
 would be set to 1 signalling it is not pressed even when it
is is because bit 4 was set to 1 meaning the game is only interested in 
the state of the directional buttons. <br><br>

The way I emulate this is I have a BYTE variabled called m_JoypadState where each bit represents the state of the <b style="color:black;background-color:#99ff99">joypad</b>
 (8 buttons
and 8 bits so it works fine). Whenever a button is pressed I set the 
correct bit in m_JoypadState to 0 and if it is not pressed it is set
to 1. If a bit in m_JoypadState goes from 1 to 0 then it means this 
button has just been pressed so a <b style="color:black;background-color:#99ff99">joypad</b> interupt is requested.<br><br>

Whenever the game reads from 0xFF00 i trap it with ReadMemory and call a
 function which looks at memory address 0xFF00 to see if the game
is interest in directional buttons or standard buttons and then I return
 a byte data which combines m_JoypadState with 0xFF00 so the game
gets the correct state of the <b style="color:black;background-color:#99ff99">joypad</b>. While I remember lets add the following to ReadMemory

<p class="code">
else if (0xFF00 == address)<br>
&nbsp;&nbsp; return GetJoypadState() ;
</p>

Before I show you the implementation of GetJoypadState I'll show you how to set m_JoypadState which GetJoypadState will need.

<p class="code">
void Emulator::KeyPressed(int key)<br>
{<br>
&nbsp;&nbsp; bool previouslyUnset = false ; <br><br>

&nbsp;&nbsp; // if setting from 1 to 0 we may have to request an interupt<br>
&nbsp;&nbsp; if (TestBit(m_JoypadState, key)==false)<br>
&nbsp;&nbsp;&nbsp;&nbsp; previouslyUnset = true ;<br><br>

&nbsp;&nbsp; // remember if a keypressed its bit is 0 not 1<br> 
&nbsp;&nbsp; m_JoypadState = BitReset(m_JoypadState, key) ;<br><br>

&nbsp;&nbsp; // button pressed<br>
&nbsp;&nbsp; bool button = true ;<br><br>

&nbsp;&nbsp; // is this a standard button or a directional button?<br>
&nbsp;&nbsp; if (key &gt; 3) <br>
&nbsp;&nbsp;&nbsp;&nbsp; button = true ;<br>
&nbsp;&nbsp; else // directional button pressed<br>
&nbsp;&nbsp;&nbsp;&nbsp; button = false ;<br><br>

&nbsp;&nbsp; BYTE keyReq = m_Rom[0xFF00] ;<br>
&nbsp;&nbsp; bool requestInterupt = false ; <br><br>

&nbsp;&nbsp; // only request interupt if the button just pressed is<br>
&nbsp;&nbsp; // the style of button the game is interested in<br>
&nbsp;&nbsp; if (button &amp;&amp; !TestBit(keyReq,5))<br>
&nbsp;&nbsp;&nbsp;&nbsp; requestInterupt = true ;<br><br>
	
&nbsp;&nbsp; // same as above but for directional button<br>
&nbsp;&nbsp; else if (!button &amp;&amp; !TestBit(keyReq,4))<br>
&nbsp;&nbsp;&nbsp;&nbsp; requestInterupt = true ;<br><br>

&nbsp;&nbsp; // request interupt<br>
&nbsp;&nbsp; if (requestInterupt &amp;&amp; !previouslyUnset)<br>
&nbsp;&nbsp;&nbsp;&nbsp; RequestInterupt(4) ;<br>
}
</p>

The function thats called when a key is released is much simpler
<p class="code">
void Emulator::KeyReleased(int key)<br>
{<br>
&nbsp;&nbsp; m_JoypadState = BitSet(m_JoypadState,key) ;<br>
}
</p>

The way I call the above functions is with SDL_KeyEvents. Whenever a key is pressed
I call KeyPressed function passing the following in as arguments

<p class="block">
SDLK_a : key = 4 <br> 
SDLK_s : key = 5 <br>
SDLK_RETURN : key = 7 <br>
SDLK_SPACE : key = 6 <br>
SDLK_RIGHT : key = 0 <br>
SDLK_LEFT : key = 1 <br>
SDLK_UP : key = 2  <br>
SDLK_DOWN : key = 3 <br>
</p>

Now we have everything needed to write the GetJoypadState function
<p class="code">
BYTE Emulator::GetJoypadState() const<br>
{<br>
&nbsp;&nbsp; BYTE res = m_Rom[0xFF00] ;<br>
&nbsp;&nbsp; // flip all the bits<br>
&nbsp;&nbsp; res ^= 0xFF ; <br><br>

&nbsp;&nbsp; // are we interested in the standard buttons?<br>
&nbsp;&nbsp; if (!TestBit(res, 4))<br>
&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp; BYTE topJoypad = m_JoypadState &gt;&gt; 4 ;<br>
&nbsp;&nbsp;&nbsp;&nbsp; topJoypad |= 0xF0 ; // turn the top 4 bits on<br>
&nbsp;&nbsp;&nbsp;&nbsp; res &amp;= topJoypad ; // show what buttons are pressed<br>
&nbsp;&nbsp; }<br>
&nbsp;&nbsp; else if (!TestBit(res,5))//directional buttons<br>
&nbsp;&nbsp; {<br>
&nbsp;&nbsp;&nbsp;&nbsp; BYTE bottomJoypad = m_JoypadState &amp; 0xF ;<br>
&nbsp;&nbsp;&nbsp;&nbsp; bottomJoypad |= 0xF0 ; <br>
&nbsp;&nbsp;&nbsp;&nbsp; res &amp;= bottomJoypad ; <br>
&nbsp;&nbsp; }<br>
&nbsp;&nbsp; return res ;<br>
}
</p>

If you are confused why m_JoypadState is shifted left 4 times when checking standard buttons is because
the standard buttons are stored in the top nibble of m_JoypadState but then need to be in the lower nibble
for when it gets logically or'd.
<br><br>
<p></p>



</div>

<div id="sidebar">
<h3><b style="color:black;background-color:#a0ffff">Gameboy</b> <b style="color:black;background-color:#ff9999">Emulation</b>:</h3>

<p>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/beginning.html">Getting Started</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/hardware.html">The Hardware</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/memory.html">Memory Control and Map</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/banking.html">ROM and RAM Banking</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/timers.html">The Timers</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/interupts.html">Interupts</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/lcd.html">LCD</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/dma.html">DMA Transfer</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/graphics.html">Graphic <b style="color:black;background-color:#ff9999">Emulation</b></a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/joypad.html"><b style="color:black;background-color:#99ff99">Joypad</b> <b style="color:black;background-color:#ff9999">Emulation</b></a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/opcodes.html">Opcode Examples</a><span class="hide"> | </span>
<a class="sidelink" href="http://www.codeslinger.co.uk/pages/projects/gameboy/finished.html">Finished Product</a><span class="hide"> | </span>

</p>

</div>
    
<div id="footer">
Copyright © 2008 <b style="color:black;background-color:#ffff66">codeslinger</b>.co.uk
</div>

</div>




</div></body></html>